using Senparc.Weixin.Helpers;
using Senparc.Weixin.MP.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
namespace Senparc.Weixin.MP.Helpers
{
    public static class EntityHelper
    {
        //public static void FillEntityWithXml<T>(this T entity, XDocument doc) where T : class, new()
        //{
        //    T arg_10_0;
        //    if ((arg_10_0 = entity) == null)
        //    {
        //        arg_10_0 = Activator.CreateInstance<T>();
        //    }
        //    entity = arg_10_0;
        //    XElement root = doc.Root;
        //    PropertyInfo[] properties = entity.GetType().GetProperties();
        //    PropertyInfo[] array = properties;
        //    for (int i = 0; i < array.Length; i++)
        //    {
        //        PropertyInfo propertyInfo = array[i];
        //        string name = propertyInfo.Name;
        //        if (root.Element(name) != null)
        //        {
        //            string name2 = propertyInfo.PropertyType.Name;
        //            if (name2 == null)
        //            {
        //                goto IL_858;
        //            }
        //            if (< PrivateImplementationDetails >{ 3274F99F - 3FA9 - 4DFD - 9069 - 1B81A9588F88}.$$method0x6000d62 - 1 == null)
        //{

        //                   < PrivateImplementationDetails >{ 3274F99F - 3FA9 - 4DFD - 9069 - 1B81A9588F88}.$$method0x6000d62 - 1 = new Dictionary<string, int>(18)
        //                   {

        //                       {
        //                           "DateTime",
        //                           0
        //                       },

        //                       {
        //                           "Boolean",
        //                           1
        //                       },

        //                       {
        //                           "Int32",
        //                           2
        //                       },

        //                       {
        //                           "Int64",
        //                           3
        //                       },

        //                       {
        //                           "Double",
        //                           4
        //                       },

        //                       {
        //                           "RequestMsgType",
        //                           5
        //                       },

        //                       {
        //                           "ResponseMsgType",
        //                           6
        //                       },

        //                       {
        //                           "Event",
        //                           7
        //                       },

        //                       {
        //                           "List`1",
        //                           8
        //                       },

        //                       {
        //                           "Music",
        //                           9
        //                       },

        //                       {
        //                           "Image",
        //                           10
        //                       },

        //                       {
        //                           "Voice",
        //                           11
        //                       },

        //                       {
        //                           "Video",
        //                           12
        //                       },

        //                       {
        //                           "ScanCodeInfo",
        //                           13
        //                       },

        //                       {
        //                           "SendLocationInfo",
        //                           14
        //                       },

        //                       {
        //                           "SendPicsInfo",
        //                           15
        //                       },

        //                       {
        //                           "ChosenBeacon",
        //                           16
        //                       },

        //                       {
        //                           "AroundBeacon",
        //                           17
        //                       }
        //                   };
        //    }
        //    int num;
        //    if (!< PrivateImplementationDetails >{ 3274F99F - 3FA9 - 4DFD - 9069 - 1B81A9588F88}.$$method0x6000d62 - 1.TryGetValue(name2, out num))
        //{
        //        goto IL_858;
        //    }
        //switch (num)
        //{
        //    case 0:
        //        propertyInfo.SetValue(entity, DateTimeHelper.GetDateTimeFromXml(root.Element(name).Value), null);
        //        break;
        //    case 1:
        //        if (!(name == "FuncFlag"))
        //        {
        //            goto IL_858;
        //        }
        //        propertyInfo.SetValue(entity, root.Element(name).Value == "1", null);
        //        break;
        //    case 2:
        //        propertyInfo.SetValue(entity, int.Parse(root.Element(name).Value), null);
        //        break;
        //    case 3:
        //        propertyInfo.SetValue(entity, long.Parse(root.Element(name).Value), null);
        //        break;
        //    case 4:
        //        propertyInfo.SetValue(entity, double.Parse(root.Element(name).Value), null);
        //        break;
        //    case 5:
        //        break;
        //    case 6:
        //        break;
        //    case 7:
        //        break;
        //    case 8:
        //        {
        //            Type[] genericArguments = propertyInfo.PropertyType.GetGenericArguments();
        //            if (genericArguments[0].Name == "Article")
        //            {
        //                List<Article> list = new List<Article>();
        //                foreach (XElement current in root.Element(name).Elements("item"))
        //                {
        //                    Article article = new Article();
        //                    article.FillEntityWithXml(new XDocument(new object[]
        //                    {
        //                           current
        //                    }));
        //                    list.Add(article);
        //                }
        //                propertyInfo.SetValue(entity, list, null);
        //            }
        //            else
        //            {
        //                if (genericArguments[0].Name == "Account")
        //                {
        //                    List<CustomerServiceAccount> list2 = new List<CustomerServiceAccount>();
        //                    foreach (XElement current in root.Elements(name))
        //                    {
        //                        CustomerServiceAccount customerServiceAccount = new CustomerServiceAccount();
        //                        customerServiceAccount.FillEntityWithXml(new XDocument(new object[]
        //                        {
        //                               current
        //                        }));
        //                        list2.Add(customerServiceAccount);
        //                    }
        //                    propertyInfo.SetValue(entity, list2, null);
        //                }
        //                else
        //                {
        //                    if (genericArguments[0].Name == "PicItem")
        //                    {
        //                        List<PicItem> list3 = new List<PicItem>();
        //                        foreach (XElement current in root.Elements(name).Elements("item"))
        //                        {
        //                            PicItem picItem = new PicItem();
        //                            string value = current.Element("PicMd5Sum").Value;
        //                            Md5Sum item = new Md5Sum
        //                            {
        //                                PicMd5Sum = value
        //                            };
        //                            picItem.item = item;
        //                            list3.Add(picItem);
        //                        }
        //                        propertyInfo.SetValue(entity, list3, null);
        //                    }
        //                    else
        //                    {
        //                        if (genericArguments[0].Name == "AroundBeacon")
        //                        {
        //                            List<AroundBeacon> list4 = new List<AroundBeacon>();
        //                            foreach (XElement current in root.Elements(name).Elements("AroundBeacon"))
        //                            {
        //                                AroundBeacon aroundBeacon = new AroundBeacon();
        //                                aroundBeacon.FillEntityWithXml(new XDocument(new object[]
        //                                {
        //                                       current
        //                                }));
        //                                list4.Add(aroundBeacon);
        //                            }
        //                            propertyInfo.SetValue(entity, list4, null);
        //                        }
        //                    }
        //                }
        //            }
        //            break;
        //        }
        //    case 9:
        //        {
        //            Music music = new Music();
        //            music.FillEntityWithXml(new XDocument(new object[]
        //            {
        //                   root.Element(name)
        //            }));
        //            propertyInfo.SetValue(entity, music, null);
        //            break;
        //        }
        //    case 10:
        //        {
        //            Image image = new Image();
        //            image.FillEntityWithXml(new XDocument(new object[]
        //            {
        //                   root.Element(name)
        //            }));
        //            propertyInfo.SetValue(entity, image, null);
        //            break;
        //        }
        //    case 11:
        //        {
        //            Voice voice = new Voice();
        //            voice.FillEntityWithXml(new XDocument(new object[]
        //            {
        //                   root.Element(name)
        //            }));
        //            propertyInfo.SetValue(entity, voice, null);
        //            break;
        //        }
        //    case 12:
        //        {
        //            Video video = new Video();
        //            video.FillEntityWithXml(new XDocument(new object[]
        //            {
        //                   root.Element(name)
        //            }));
        //            propertyInfo.SetValue(entity, video, null);
        //            break;
        //        }
        //    case 13:
        //        {
        //            ScanCodeInfo scanCodeInfo = new ScanCodeInfo();
        //            scanCodeInfo.FillEntityWithXml(new XDocument(new object[]
        //            {
        //                   root.Element(name)
        //            }));
        //            propertyInfo.SetValue(entity, scanCodeInfo, null);
        //            break;
        //        }
        //    case 14:
        //        {
        //            SendLocationInfo sendLocationInfo = new SendLocationInfo();
        //            sendLocationInfo.FillEntityWithXml(new XDocument(new object[]
        //            {
        //                   root.Element(name)
        //            }));
        //            propertyInfo.SetValue(entity, sendLocationInfo, null);
        //            break;
        //        }
        //    case 15:
        //        {
        //            SendPicsInfo sendPicsInfo = new SendPicsInfo();
        //            sendPicsInfo.FillEntityWithXml(new XDocument(new object[]
        //            {
        //                   root.Element(name)
        //            }));
        //            propertyInfo.SetValue(entity, sendPicsInfo, null);
        //            break;
        //        }
        //    case 16:
        //        {
        //            ChosenBeacon chosenBeacon = new ChosenBeacon();
        //            chosenBeacon.FillEntityWithXml(new XDocument(new object[]
        //            {
        //                   root.Element(name)
        //            }));
        //            propertyInfo.SetValue(entity, chosenBeacon, null);
        //            break;
        //        }
        //    case 17:
        //        {
        //            AroundBeacon aroundBeacon2 = new AroundBeacon();
        //            aroundBeacon2.FillEntityWithXml(new XDocument(new object[]
        //            {
        //                   root.Element(name)
        //            }));
        //            propertyInfo.SetValue(entity, aroundBeacon2, null);
        //            break;
        //        }
        //    default:
        //        goto IL_858;
        //}
        //goto IL_87A;
        //IL_858:
        //propertyInfo.SetValue(entity, root.Element(name).Value, null);
        //}
        public static XDocument ConvertEntityToXml<T>(this T entity) where T : class, new()
        {
            T arg_17_0;
            if ((arg_17_0 = entity) == null)
            {
                arg_17_0 = Activator.CreateInstance<T>();
            }
            entity = arg_17_0;
            XDocument xDocument = new XDocument();
            xDocument.Add(new XElement("xml"));
            XElement root = xDocument.Root;
            List<string> list = new List<string>
            {
                "ToUserName",
                "FromUserName",
                "CreateTime",
                "MsgType"
            };
            if (entity is ResponseMessageNews)
            {
                list.AddRange(new string[]
                {
                    "ArticleCount",
                    "Articles",
                    "FuncFlag",
                    "Title ",
                    "Description ",
                    "PicUrl",
                    "Url"
                });
            }
            else
            {
                if (entity is ResponseMessageTransfer_Customer_Service)
                {
                    list.AddRange(new string[]
                    {
                        "TransInfo",
                        "KfAccount",
                        "FuncFlag"
                    });
                }
                else
                {
                    if (entity is ResponseMessageMusic)
                    {
                        list.AddRange(new string[]
                        {
                            "Music",
                            "FuncFlag",
                            "ThumbMediaId",
                            "Title ",
                            "Description ",
                            "MusicUrl",
                            "HQMusicUrl"
                        });
                    }
                    else
                    {
                        if (entity is ResponseMessageImage)
                        {
                            list.AddRange(new string[]
                            {
                                "Image",
                                "MediaId "
                            });
                        }
                        else
                        {
                            if (entity is ResponseMessageVoice)
                            {
                                list.AddRange(new string[]
                                {
                                    "Voice",
                                    "MediaId "
                                });
                            }
                            else
                            {
                                if (entity is ResponseMessageVideo)
                                {
                                    list.AddRange(new string[]
                                    {
                                        "Video",
                                        "MediaId ",
                                        "Title",
                                        "Description"
                                    });
                                }
                                else
                                {
                                    list.AddRange(new string[]
                                    {
                                        "Content",
                                        "FuncFlag"
                                    });
                                }
                            }
                        }
                    }
                }
            }
            Func<string, int> orderByPropName = new Func<string, int>(list.IndexOf);
            List<PropertyInfo> list2 = (
                from p in entity.GetType().GetProperties()
                orderby orderByPropName(p.Name)
                select p).ToList<PropertyInfo>();
            foreach (PropertyInfo current in list2)
            {
                string name = current.Name;
                if (name == "Articles")
                {
                    XElement xElement = new XElement("Articles");
                    List<Article> list3 = current.GetValue(entity, null) as List<Article>;
                    foreach (Article current2 in list3)
                    {
                        IEnumerable<XElement> content = current2.ConvertEntityToXml<Article>().Root.Elements();
                        xElement.Add(new XElement("item", content));
                    }
                    root.Add(xElement);
                }
                else
                {
                    if (name == "TransInfo")
                    {
                        XElement xElement2 = new XElement("TransInfo");
                        List<CustomerServiceAccount> list4 = current.GetValue(entity, null) as List<CustomerServiceAccount>;
                        foreach (CustomerServiceAccount current3 in list4)
                        {
                            IEnumerable<XElement> content2 = current3.ConvertEntityToXml<CustomerServiceAccount>().Root.Elements();
                            xElement2.Add(content2);
                        }
                        root.Add(xElement2);
                    }
                    else
                    {
                        if (name == "Music" || name == "Image" || name == "Video" || name == "Voice")
                        {
                            XElement xElement3 = new XElement(name);
                            object value = current.GetValue(entity, null);
                            IEnumerable<XElement> content = value.ConvertEntityToXml<object>().Root.Elements();
                            xElement3.Add(content);
                            root.Add(xElement3);
                        }
                        else
                        {
                            if (name == "PicList")
                            {
                                XElement xElement4 = new XElement("PicList");
                                List<PicItem> list5 = current.GetValue(entity, null) as List<PicItem>;
                                foreach (PicItem current4 in list5)
                                {
                                    IEnumerable<XElement> content3 = current4.ConvertEntityToXml<PicItem>().Root.Elements();
                                    xElement4.Add(content3);
                                }
                                root.Add(xElement4);
                            }
                            else
                            {
                                string name2 = current.PropertyType.Name;
                                if (name2 == null)
                                {
                                    goto IL_77B;
                                }
                                //                        if (< PrivateImplementationDetails >{ 3274F99F - 3FA9 - 4DFD - 9069 - 1B81A9588F88}.$$method0x6000d63 - 1 == null)
                                //{

                                //                            < PrivateImplementationDetails >{ 3274F99F - 3FA9 - 4DFD - 9069 - 1B81A9588F88}.$$method0x6000d63 - 1 = new Dictionary<string, int>(6)
                                //                            {

                                //                                {
                                //                                    "String",
                                //                                    0
                                //                                },

                                //                                {
                                //                                    "DateTime",
                                //                                    1
                                //                                },

                                //                                {
                                //                                    "Boolean",
                                //                                    2
                                //                                },

                                //                                {
                                //                                    "ResponseMsgType",
                                //                                    3
                                //                                },

                                //                                {
                                //                                    "Article",
                                //                                    4
                                //                                },

                                //                                {
                                //                                    "TransInfo",
                                //                                    5
                                //                                }
                                //                            };
                                //                        }
                                //                        int num;
                                //                        if (!< PrivateImplementationDetails >{ 3274F99F - 3FA9 - 4DFD - 9069 - 1B81A9588F88}.$$method0x6000d63 - 1.TryGetValue(name2, out num))
                                //{
                                //                            goto IL_77B;
                                //                        }
                                //                        switch (num)
                                //                        {
                                //                            case 0:
                                //                                root.Add(new XElement(name, new XCData((current.GetValue(entity, null) as string) ?? "")));
                                //                                break;
                                //                            case 1:
                                //                                root.Add(new XElement(name, DateTimeHelper.GetWeixinDateTime((DateTime)current.GetValue(entity, null))));
                                //                                break;
                                //                            case 2:
                                //                                if (!(name == "FuncFlag"))
                                //                                {
                                //                                    goto IL_77B;
                                //                                }
                                //                                root.Add(new XElement(name, ((bool)current.GetValue(entity, null)) ? "1" : "0"));
                                //                                break;
                                //                            case 3:
                                //                                root.Add(new XElement(name, new XCData(current.GetValue(entity, null).ToString().ToLower())));
                                //                                break;
                                //                            case 4:
                                //                                root.Add(new XElement(name, current.GetValue(entity, null).ToString().ToLower()));
                                //                                break;
                                //                            case 5:
                                //                                root.Add(new XElement(name, current.GetValue(entity, null).ToString().ToLower()));
                                //                                break;
                                //                            default:
                                //                                goto IL_77B;
                                //                        }
                                continue;
                                IL_77B:
                                if (current.PropertyType.IsClass && current.PropertyType.IsPublic)
                                {
                                    object value2 = current.GetValue(entity, null);
                                    IEnumerable<XElement> content = value2.ConvertEntityToXml<object>().Root.Elements();
                                    root.Add(new XElement(name, content));
                                }
                                else
                                {
                                    root.Add(new XElement(name, current.GetValue(entity, null)));
                                }
                            }
                        }
                    }
                }
            }
            return xDocument;
        }
        public static string ConvertEntityToXmlString<T>(this T entity) where T : class, new()
        {
            return entity.ConvertEntityToXml<T>().ToString();
        }
        public static T CreateResponseMessage<T>(this IRequestMessageBase requestMessage) where T : ResponseMessageBase
        {
            return ResponseMessageBase.CreateFromRequestMessage<T>(requestMessage);
        }
        public static IResponseMessageBase CreateResponseMessage(this string xml)
        {
            return ResponseMessageBase.CreateFromResponseXml(xml);
        }
        public static bool IsFromScene(this RequestMessageEvent_Subscribe requestMessage)
        {
            return !string.IsNullOrEmpty(requestMessage.EventKey);
        }
    }
}
